package br.uniceub.fsw.agenda.model.facade;

import br.uniceub.fsw.agenda.exception.BusinessException;
import br.uniceub.fsw.agenda.exception.DatabaseException;
import br.uniceub.fsw.agenda.model.dao.*;
import br.uniceub.fsw.agenda.model.vo.*;
import br.uniceub.fsw.agenda.util.StringUtils;
import java.util.ArrayList;
import java.util.List;

/**
 *
 * @author Bruno
 */
public class ManterPessoaFacade extends GenericFacade {

    /**
     * Busca todos os Menus
     * @return List com objetos Menu
     * @throws br.uniceub.fsw.agenda.exception.DatabaseException
     * @throws br.uniceub.fsw.agenda.exception.BusinessException
     */
    public List<MenuVO> findAllMenu() throws DatabaseException, BusinessException {
        try {
            MenuDAO dao = new MenuDAO(getConnection());
            return dao.findAll();
        } finally {
            closeConnection();
        }
    }

    /**
     * Busca todos os Tipod de Telefone
     * @return List com objetos TipoTefelone
     * @throws br.uniceub.fsw.agenda.exception.DatabaseException
     * @throws br.uniceub.fsw.agenda.exception.BusinessException
     */
    public List<TipoTelefoneVO> findAllTipoTelefone() throws DatabaseException, BusinessException {
        try {
            TipoTelefoneDAO dao = new TipoTelefoneDAO(getConnection());
            return dao.findAll();
        } finally {
            closeConnection();
        }
    }

    /**
     * Busca todos os Telefone
     * @return List com objetos Tefelone
     * @throws br.uniceub.fsw.agenda.exception.DatabaseException
     * @throws br.uniceub.fsw.agenda.exception.BusinessException
     */
    public List<PessoaTelefoneVO> findAllPessoaTelefoneByPessoa(Integer idPessoa) throws DatabaseException, BusinessException {
        try {
            PessoaTelefoneDAO dao = new PessoaTelefoneDAO(getConnection());
            
            PessoaVO pessoa = new PessoaVO();
            
            pessoa.setIdPessoa(idPessoa);
            
            if(idPessoa == null) {
                return dao.findAll();
            } else {
                return dao.findAllByPessoa(pessoa);
            }
        } finally {
            closeConnection();
        }
    }

    /**
     * Busca todos os Telefone
     * @param idPessoa código da pessoa
     * @return List com objetos Tefelone
     * @throws br.uniceub.fsw.agenda.exception.DatabaseException
     * @throws br.uniceub.fsw.agenda.exception.BusinessException
     */
    public List<PessoaTelefoneVO> findAllPessoaTelefone(Integer idPessoa) throws DatabaseException, BusinessException {
        try {
            PessoaTelefoneDAO dao = new PessoaTelefoneDAO(getConnection());
            
            PessoaVO pessoa = new PessoaVO();
            
            pessoa.setIdPessoa(idPessoa);
            
            if(idPessoa != null) {
                return dao.findAllByPessoa(pessoa);
            }
            
            return null;
        } finally {
            closeConnection();
        }
    }

    /**
     * Busca Pessoa por cpf
     * @return List com objetos Pessoa
     * @throws br.uniceub.fsw.agenda.exception.DatabaseException
     * @throws br.uniceub.fsw.agenda.exception.BusinessException
     */
    public PessoaVO findPessoaByCpf(Long nrCpf) throws DatabaseException, BusinessException {
        try {
            PessoaDAO dao = new PessoaDAO(getConnection());
            
            PessoaVO pessoa = dao.findByCpf(nrCpf);
            
            if(pessoa.getIdPessoa() == null) {
                throw new BusinessException("Nenhum registro encontrado.");
            }
            
            return pessoa;
        } finally {
            closeConnection();
        }
    }

    /**
     * Busca todas as Pessoas
     * @return List com objetos Pessoa
     * @throws br.uniceub.fsw.agenda.exception.DatabaseException
     * @throws br.uniceub.fsw.agenda.exception.BusinessException
     */
    public List<PessoaVO> findAllPessoa() throws DatabaseException, BusinessException {
        try {
            PessoaDAO dao = new PessoaDAO(getConnection());
            return dao.findAll();
        } finally {
            closeConnection();
        }
    }
    
    public List<PessoaVO> findAllPessoa(String noPessoa, Long nrCpf)
            throws DatabaseException, BusinessException {
        try {
            PessoaDAO dao = new PessoaDAO(getConnection());
            if(StringUtils.isNullOrEmpty(noPessoa) && (nrCpf == null)) {
                return dao.findAll();
            }
            
            // Busca as Pessoas pelo nome ou parte dele
            if(!StringUtils.isNullOrEmpty(noPessoa) && (nrCpf == null)) {
                return dao.findAllByNome(noPessoa);
            }
            
            // Caso os dois campos sejam preenchidos, ignora o nome e busca pelo cpf
            if(nrCpf != null) {
                PessoaVO pessoa = dao.findByCpf(nrCpf);
                List<PessoaVO> listaPessoa = null;
                if(pessoa != null) {
                    listaPessoa = new ArrayList<PessoaVO>();
                    listaPessoa.add(pessoa);
                }
                return listaPessoa;
            }
            
            return null;
        } finally {
            closeConnection();
        }
    }

    /**
     * Busca todas as Pessoas pelo nome
     * @return List com objetos Pessoa
     * @throws br.uniceub.fsw.agenda.exception.DatabaseException
     * @throws br.uniceub.fsw.agenda.exception.BusinessException
     */
    public List<PessoaVO> findAllPessoaByNome(String noPessoa) throws DatabaseException, BusinessException {
        try {
            PessoaDAO dao = new PessoaDAO(getConnection());
            return dao.findAllByNome(noPessoa);
        } finally {
            closeConnection();
        }
    }

    /**
     * Busca uma Pessoa pelo id
     * @return Pessoa
     * @throws br.uniceub.fsw.agenda.exception.DatabaseException
     * @throws br.uniceub.fsw.agenda.exception.BusinessException
     */
    public PessoaVO findPessoaById(Integer idPessoa) throws DatabaseException, BusinessException {
        try {
            PessoaDAO dao = new PessoaDAO(getConnection());
            return dao.findById(idPessoa);
        } finally {
            closeConnection();
        }
    }

    /**
     * Busca todos os Tipos de Logradouro
     * @return List com objetos TipoTefelone
     * @throws br.uniceub.fsw.agenda.exception.DatabaseException
     * @throws br.uniceub.fsw.agenda.exception.BusinessException
     */
    public List<TipoLogradouroVO> findAllTipoLogradouro() throws DatabaseException, BusinessException {
        try {
            TipoLogradouroDAO dao = new TipoLogradouroDAO(getConnection());
            return dao.findAll();
        } finally {
            closeConnection();
        }
    }

    /**
     * Busca todos as UFs
     * @return List com objetos UF
     * @throws br.uniceub.fsw.agenda.exception.DatabaseException
     * @throws br.uniceub.fsw.agenda.exception.BusinessException
     */
    public List<UFVO> findAllUF() throws DatabaseException, BusinessException {
        try {
            UFDAO dao = new UFDAO(getConnection());
            return dao.findAll();
        } finally {
            closeConnection();
        }
    }

    /**
     * Busca todos os Cidade
     * @return List com objetos Cidade
     * @throws br.uniceub.fsw.agenda.exception.DatabaseException
     * @throws br.uniceub.fsw.agenda.exception.BusinessException
     */
    public List<CidadeVO> findAllCidade() throws DatabaseException, BusinessException {
        try {
            CidadeDAO dao = new CidadeDAO(getConnection());
            return dao.findAll();
        } finally {
            closeConnection();
        }
    }

    /**
     * Busca todas as Cidades ou se a sigla da UF estiver preenchida
     * buscar somente as da UF
     * @return List com objetos Cidade
     * @throws br.uniceub.fsw.agenda.exception.DatabaseException
     * @throws br.uniceub.fsw.agenda.exception.BusinessException
     */
    public List<CidadeVO> findAllCidade(String sgUf) throws DatabaseException, BusinessException {
        try {
            CidadeDAO dao = new CidadeDAO(getConnection());
            
            if(StringUtils.isNullOrEmpty(sgUf)) {
                dao.findAll();
            } else {
                dao.findAllByUF(sgUf);
            }
            
            return dao.findAll();
        } finally {
            closeConnection();
        }
    }

    /**
     * Busca todas as Cidades
     * @param sgUf
     * @return List com objetos Cidade
     * @throws br.uniceub.fsw.agenda.exception.DatabaseException
     * @throws br.uniceub.fsw.agenda.exception.BusinessException
     */
    public List<CidadeVO> findAllCidadeByUF(String sgUf) throws DatabaseException, BusinessException {
        try {
            CidadeDAO dao = new CidadeDAO(getConnection());
            return dao.findAllByUF(sgUf);
        } finally {
            closeConnection();
        }
    }

    /**
     * Busca todos os Bairro
     * @return List com objetos Bairro
     * @throws br.uniceub.fsw.agenda.exception.DatabaseException
     * @throws br.uniceub.fsw.agenda.exception.BusinessException
     */
    public List<BairroVO> findAllBairro() throws DatabaseException, BusinessException {
        try {
            BairroDAO dao = new BairroDAO(getConnection());
            return dao.findAll();
        } finally {
            closeConnection();
        }
    }

    /**
     * Busca todos os Bairros ou se o idCidade estiver preenchido
     * busca os bairros pertencentes a uma cidade
     * @return List com objetos Bairro
     * @throws br.uniceub.fsw.agenda.exception.DatabaseException
     * @throws br.uniceub.fsw.agenda.exception.BusinessException
     */
    public List<BairroVO> findAllBairro(Integer idCidade) throws DatabaseException, BusinessException {
        try {
            BairroDAO dao = new BairroDAO(getConnection());
            
            if(idCidade == null) {
                dao.findAll();
            } else {
                dao.findAllByCidade(idCidade);
            }
            
            return dao.findAll();
        } finally {
            closeConnection();
        }
    }

    /**
     * Busca todos os Bairro
     * @return List com objetos Bairro
     * @throws br.uniceub.fsw.agenda.exception.DatabaseException
     * @throws br.uniceub.fsw.agenda.exception.BusinessException
     */
    public List<BairroVO> findAllBairroByCidade(Integer idCidade) throws DatabaseException, BusinessException {
        try {
            BairroDAO dao = new BairroDAO(getConnection());
            return dao.findAllByCidade(idCidade);
        } finally {
            closeConnection();
        }
    }

    /**
     * Busca uma Cidade
     * @param idCidade
     * @return List com objetos Cidade
     * @throws br.uniceub.fsw.agenda.exception.DatabaseException
     * @throws br.uniceub.fsw.agenda.exception.BusinessException
     */
    public CidadeVO findCidadeById(Integer idCidade) throws DatabaseException, BusinessException {
        try {
            CidadeDAO dao = new CidadeDAO(getConnection());
            return dao.findById(idCidade);
        } finally {
            closeConnection();
        }
    }

    /**
     * Busca o TipoLogradouro pela id
     * @param idTipoLogradouro id do TipoLogradouro
     * @return objeto TipoLogradouro
     * @throws br.uniceub.fsw.agenda.exception.DatabaseException
     * @throws br.uniceub.fsw.agenda.exception.BusinessException
     */
    public TipoLogradouroVO findTipoLogradouroById(Integer idTipoLogradouro) throws DatabaseException, BusinessException {
        try {
            TipoLogradouroDAO dao = new TipoLogradouroDAO(getConnection());
            return dao.findById(idTipoLogradouro);
        } finally {
            closeConnection();
        }
    }

    /**
     * Busca a TipoTelefone pela id
     * @param idTipoTelefone id do TipoTelefone
     * @return objeto TipoTelefone
     * @throws br.uniceub.fsw.agenda.exception.DatabaseException
     * @throws br.uniceub.fsw.agenda.exception.BusinessException
     */
    public TipoTelefoneVO findTipoTelefoneById(Integer idTipoTelefone) throws DatabaseException, BusinessException {
        try {
            TipoTelefoneDAO dao = new TipoTelefoneDAO(getConnection());
            return dao.findById(idTipoTelefone);
        } finally {
            closeConnection();
        }
    }

    /**
     * Busca a Bairro pela id
     * @param idBairro id do Bairro
     * @return objeto Bairro
     * @throws br.uniceub.fsw.agenda.exception.DatabaseException
     * @throws br.uniceub.fsw.agenda.exception.BusinessException
     */
    public BairroVO findBairroById(Integer idBairro) throws DatabaseException, BusinessException {
        try {
            BairroDAO dao = new BairroDAO(getConnection());
            return dao.findById(idBairro);
        } finally {
            closeConnection();
        }
    }

    /**
     * Busca um Logradouro pelo id
     * @return Logradouro
     * @throws br.uniceub.fsw.agenda.exception.DatabaseException
     * @throws br.uniceub.fsw.agenda.exception.BusinessException
     */
    public LogradouroVO findLogradouroById(Integer idLogradouro) throws DatabaseException, BusinessException {
        try {
            LogradouroDAO dao = new LogradouroDAO(getConnection());
            return dao.findById(idLogradouro);
        } finally {
            closeConnection();
        }
    }

    /**
     * Busca um Logradouro pelo cep
     * @return Logradouro
     * @throws br.uniceub.fsw.agenda.exception.DatabaseException
     * @throws br.uniceub.fsw.agenda.exception.BusinessException
     */
    public LogradouroVO findLogradouroByCep(Integer nrCep) throws DatabaseException, BusinessException {
        try {
            LogradouroDAO dao = new LogradouroDAO(getConnection());
            
            if(nrCep == null)
            {
                return null;
            }
            
            return dao.findByCep(nrCep);
        } finally {
            closeConnection();
        }
    }

    /**
     * Busca um Telefone pelo numero
     * @return Telefone
     * @throws br.uniceub.fsw.agenda.exception.DatabaseException
     * @throws br.uniceub.fsw.agenda.exception.BusinessException
     */
    public TelefoneVO findTelefoneByNumero(Long nrTelefone) throws DatabaseException, BusinessException {
        try {
            TelefoneDAO dao = new TelefoneDAO(getConnection());
            
            if(nrTelefone == null) {
                return null;
            }
            
            return dao.findByNumero(nrTelefone);
        } finally {
            closeConnection();
        }
    }

    /**
     * Insere um novo pessoaTelefone.
     * @param pessoaTelefone
     * @return ID auto-increment gerada pra esse registro
     * @throws br.uniceub.fsw.agenda.exception.BusinessException 
     * @throws br.uniceub.fsw.agenda.exception.DatabaseException
     */
    public Integer inserirPessoaTelefone(PessoaTelefoneVO pessoaTelefone) throws BusinessException, DatabaseException {
        try {
            PessoaTelefoneDAO dao = new PessoaTelefoneDAO(getConnection());
            return dao.insert(pessoaTelefone);            
        } finally {
            closeConnection();
        }        
    }
    
    /**
     * Insere um novo telefone.
     * @param telefone
     * @return ID auto-increment gerada pra esse registro
     * @throws br.uniceub.fsw.agenda.exception.BusinessException 
     * @throws br.uniceub.fsw.agenda.exception.DatabaseException
     */
    public Integer inserirTelefone(TelefoneVO telefone) throws BusinessException, DatabaseException {
        try {
            TelefoneDAO dao = new TelefoneDAO(getConnection());
            return dao.insert(telefone);            
        } finally {
            closeConnection();
        }        
    }
    
    /**
     * Exclui uma pessoaTelefone.
     * @param pessoa
     * @param telefone
     * @return ID auto-increment gerada pra esse registro
     * @throws br.uniceub.fsw.agenda.exception.BusinessException 
     * @throws br.uniceub.fsw.agenda.exception.DatabaseException
     */
    public void excluirPessoaTelefone(PessoaTelefoneVO pessoaTelefone) throws BusinessException, DatabaseException {
        try {
            PessoaTelefoneDAO dao = new PessoaTelefoneDAO(getConnection());
            dao.delete(pessoaTelefone);
        } finally {
            closeConnection();
        }        
    }
    
    /**
     * Insere um novo logradouro.
     * @param logradouro
     * @return ID auto-increment gerada pra esse registro
     * @throws br.uniceub.fsw.agenda.exception.BusinessException 
     * @throws br.uniceub.fsw.agenda.exception.DatabaseException
     */
    public Integer inserirLogradouro(LogradouroVO logradouro) throws BusinessException, DatabaseException {
        try {
            LogradouroDAO dao = new LogradouroDAO(getConnection());
            return dao.insert(logradouro);            
        } finally {
            closeConnection();
        }        
    }
    
    /**
     * Insere uma nova pessoa.
     * @param pessoa
     * @return ID auto-increment gerada pra esse registro
     * @throws br.uniceub.fsw.agenda.exception.BusinessException 
     * @throws br.uniceub.fsw.agenda.exception.DatabaseException
     */
    public Integer inserirPessoa(PessoaVO pessoa) throws BusinessException, DatabaseException {
        try {
            PessoaDAO dao = new PessoaDAO(getConnection());

            String noPessoa = pessoa.getNoPessoa();
            Long nrCpf = pessoa.getNrCpf();
            LogradouroVO logradouro = pessoa.getLogradouro();
            
            //tratamento de erros
            if(StringUtils.isNullOrEmpty(noPessoa)) {
                throw new BusinessException("Nome da Pessoa é obrigatório.");
            }
            if(nrCpf == null) {
                throw new BusinessException("CPF é obrigatório.");
            }
            if(logradouro == null || logradouro.getIdLogradouro() == null) {
                throw new BusinessException("Endereço é obrigatório.");
            }
            
            return dao.insert(pessoa);            
        } finally {
            closeConnection();
        }        
    }
    
    /**
     * Altera uma pessoa.
     * @param pessoa
     * @return ID auto-increment gerada pra esse registro
     * @throws br.uniceub.fsw.agenda.exception.BusinessException 
     * @throws br.uniceub.fsw.agenda.exception.DatabaseException
     */
    public void alterarPessoa(PessoaVO pessoa) throws BusinessException, DatabaseException {
        try {
            PessoaDAO dao = new PessoaDAO(getConnection());

            String noPessoa = pessoa.getNoPessoa();
            Long nrCpf = pessoa.getNrCpf();
            LogradouroVO logradouro = pessoa.getLogradouro();
            
            //tratamento de erros
            if(StringUtils.isNullOrEmpty(noPessoa)) {
                throw new BusinessException("Nome da Pessoa é obrigatório.");
            }
            if(nrCpf == null) {
                throw new BusinessException("CPF é obrigatório.");
            }
            if(logradouro == null || logradouro.getIdLogradouro() == null) {
                throw new BusinessException("Endereço é obrigatório.");
            }
            
            dao.update(pessoa);            
        } finally {
            closeConnection();
        }        
    }
    
    /**
     * Exclui um pessoa.
     * @param pessoa
     * @throws br.uniceub.fsw.agenda.exception.BusinessException 
     * @throws br.uniceub.fsw.agenda.exception.DatabaseException
     */
    public void excluirPessoa(Integer idPessoa) throws BusinessException, DatabaseException {
        try {
            PessoaDAO dao = new PessoaDAO(getConnection());
            dao.delete(idPessoa);
        } finally {
            closeConnection();
        }        
    }

}
